package myJs

import japgolly.scalajs.react.vdom.all.s
import myJs.Implicits._
import myJs.Utils.layer
import myJs.myPkg._
import myJs.myPkg.jquery._
import myJs.tool.Tool
import org.scalajs.dom.ext.Ajax
import org.scalajs.dom.{Element, document}
import scalatags.Text.all._
import shared.VarTool

import scala.collection.immutable.SeqMap
import scala.concurrent.ExecutionContext.Implicits.global
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.JSON

/**
 * Created by yz on 6/5/2021
 */
object CellBrowse {

  val tabId = "cell"
  val tableId = "table"
  val formId = "form"

  def init = {
    registerEvent
    refreshCellTypesMethod
    refreshCellOrigins.zip(refreshCellTypes).zip(refreshDiffGroup).flatMap{x=>
      bootStrapValidator
      initTable()
      refreshTable
    }
  }

  def refreshDiffGroup = {
    val url = g.jsRoutes.controllers.CellController.getAllDiffGroup().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      val data = JSON.parse(xhr.responseText).toJArS
      val array = data.map { kind =>
        js.Dictionary("text" -> kind, "id" -> kind)
      }
      val options = Select2Options.multiple(true).allowClear(true).placeholder("click to choose").dictData(array)
      $(s"#${tabId}").findInputByName("diffSamples[]").select2(options)
    }
  }

  def refreshCellTypesMethod = {
    val data = SeqMap("union" -> "Union", "inter" -> "Intersection")
    val array = data.map { case (id, text) =>
      js.Dictionary("text" -> text, "id" -> id)
    }
    val options = Select2Options.dictData(array.toJSArray)
    Tool.getInputByName("cellTypesMethod").select2(options)
  }

  def registerEvent = {
    $(document.body).on("click", s"#${tabId} .mySearch", "", (y: Element) => {
      mySearch
    })
  }

  def mySearch = {
    val formJq = $(s"#${tabId} #${formId}")
    val bv = formJq.bv
    bv.validate()
    val valid = bv.isValid()
    if (valid) {
      val element = div(id := "content",
        span(id := "info", "searching...",
          span(id := "progress", "。。。")), " ",
        img(src := "/assets/images/running2.gif", cls := "runningImage", width := 30, height := 20)
      ).render
      val layerOptions = LayerOptions.title(Tool.zhInfo).closeBtn(0).skin("layui-layer-molv").btn(js.Array())
      val index = layer.alert(element, layerOptions)
      val url = g.jsRoutes.controllers.CellController.search().url.toString
      val formData = formJq.serialize()
      Ajax.post(url = s"${url}", data = s"${formData}", headers = Map("Content-Type" -> "application/x-www-form-urlencoded")).map { xhr =>
        val data = xhr.responseText.toJArJDS
        layer.close(index)
        $(s"#${tabId} #${tableId}").bootstrapTable("load", data)
      }
    }
  }

  def refreshCellOrigins = {
    val url = g.jsRoutes.controllers.CellController.getAllCellOrigins().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      val data = JSON.parse(xhr.responseText).toJArS
      val array = data.map { v =>
        js.Dictionary("text" -> v, "id" -> v)
      }
      val options = Select2Options.multiple(true).allowClear(true).placeholder("click to choose").dictData(array)
      $(s"#${tabId}").findInputByName("cellOrigins[]").select2(options)
    }
  }

  def refreshCellTypes = {
    val url = g.jsRoutes.controllers.CellController.getAllCellTypes().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      val data = JSON.parse(xhr.responseText).toJArS
      val array = data.map { v =>
        js.Dictionary("text" -> v, "id" -> v)
      }
      val options = Select2Options.multiple(true).allowClear(true).placeholder("click to choose").dictData(array)
      $(s"#${tabId}").findInputByName("cellTypes[]").select2(options)
    }
  }

  def tbFmt(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[js.Any]) => {
    columnName match {
      case "pathwayName" =>
        a(href := s"${row("msigdbLink")}", target := "_blank", v.toString)
      case "cellName"=>
        val url = g.jsRoutes.controllers.CellController.detailInfo().url.toString
        a(href:=s"${url}?id=${v}",target:="_blank",v.toString)
      case _ => v
    }
  }

  def expStyle(columnName: String): js.Function = (v: js.Any, row: js.Dictionary[Any]) => columnName match {
    case "cellName"=>js.Dictionary("css" -> js.Dictionary(
      "min-width" -> "130px"
    ))

    case _ => v
  }

  val plotColumn = js.Array(
    ColumnOptions.field("operate").title("Plot").formatter(plotFmt).filterControl("clear")
  )

  def plotFmt: js.Function = {
    (v: js.Any, row: js.Dictionary[js.Any]) =>
      val url = g.jsRoutes.controllers.DetailController.detailInfo().url.toString
      a(href := s"${url}?id=${row("cellName")}&kind=${VarTool.cellKind}&tab=${VarTool.profileTabId}", target := "_blank", `class` := "myBlood",
        span(cls := "fa fa-picture-o")
      )

  }

  def initTable(tableJq:JQuery=$(s"#${tabId} #${tableId}")) = {
    val map = VarTool.cellMap
    val columnNames = map.keyList
    val columns = columnNames.map { columnName =>
      val title = map.getOrElse(columnName, columnName)
      val fmt = tbFmt(columnName)
      val style = expStyle(columnName)
      val sortable=true
      val basicOptions = ColumnOptions.field(columnName).title(title).titleTooltip(title).sortable(true).formatter(fmt).cellStyle(style)
      columnName match {
        case x if x=="cellName" =>
          val xCap=x.capitalize
          val thClass = if (sortable) s"my${xCap}SortTh" else s"my${xCap}Th"
          basicOptions.`class`(thClass)
        case _ => basicOptions
      }
    }.concat(plotColumn)
    val exportOptions = ExportOptions.fileName("data")
    val options = TableOptions.columns(columns.toJSArray).searchOnButton(false).filterControl(false).
      exportOptions(exportOptions).exportTypes(js.Array("csv")).showExport(true).exportDataType("all")
    tableJq.bootstrapTable(options)
  }

  def refreshTable = {
    val url = g.jsRoutes.controllers.CellController.getHead1000().url.toString
    Ajax.get(url = s"${url}").map { xhr =>
      val data = xhr.responseText.toJArJDS
      $(s"#${tabId} #${tableId}").bootstrapTable("load", data)
    }
  }

  def bootStrapValidator = {
    val maxNumber = Double.MaxValue
    val dict = js.Dictionary(
      "feedbackIcons" -> js.Dictionary(
        "valid" -> "glyphicon glyphicon-ok",
        "invalid" -> "glyphicon glyphicon-remove",
        "validating" -> "glyphicon glyphicon-refresh",
      ),
      "fields" -> {
        js.Dictionary(
          "start" -> js.Dictionary(
            "validators" -> js.Dictionary(
              "integer" -> js.Dictionary(
                "message" -> "position start must be an integer！",
              ),
              "between" -> js.Dictionary(
                "min" -> 1,
                "max" -> maxNumber,
                "message" -> "position start must be greater than 0！",
              ),
            )
          ),
          "end" -> js.Dictionary(
            "validators" -> js.Dictionary(
              "integer" -> js.Dictionary(
                "message" -> "position end must be an integer！",
              ),
              "between" -> js.Dictionary(
                "min" -> "start",
                "max" -> maxNumber,
                "message" -> "position end must be greater than start！",
              ),
            )
          ),
          "dfMin" -> js.Dictionary(
            "validators" -> js.Dictionary(
              "numeric" -> js.Dictionary(
                "message" -> "Detection frequency's min value be an numeric！",
              ),
              "between" -> js.Dictionary(
                "min" -> 0,
                "max" -> 1,
                "message" -> "Detection frequency's min must be between 0 and 1！",
              ),
            )
          ),
          "dfMax" -> js.Dictionary(
            "validators" -> js.Dictionary(
              "numeric" -> js.Dictionary(
                "message" -> "Detection frequency's max value be an numeric！",
              ),
              "between" -> js.Dictionary(
                "min" -> "dfMin",
                "max" -> 1,
                "message" -> "Detection frequency's max must be between the min value and 1！",
              ),
            )
          ),
        )
      }
    )
    g.$(s"#${tabId} #${formId}").bootstrapValidator(dict)
  }


}
